#pragma once
#include <rapidjson/document.h>
#include <yaml-cpp/yaml.h>
#include <unordered_map>
#include <map>
#include <string>
#include <atomic>
#include <thread>
#include <list>

#include "ws_connection.h"
#include "config.h"
#include "def.h"
#include "shm_utils.h"
#include "https_connection.h"
#include "https_connection_pool.h"
#include "exchange.h"

struct BinanceOrderBook: public OrderBook {
    long long int lastUpdateId;
};

struct BinanceOrderBookUpdate {
    long long int U;
    long long int u;
    long long int pu;
    std::string symbol;
    std::vector<std::pair<uint64_t, double>> bids; // 价格，数量
    std::vector<std::pair<uint64_t, double>> asks; // 价格，数量
};

class BinanceClient : public std::enable_shared_from_this<BinanceClient>, public Exchange {
public:
    explicit BinanceClient(const std::string& config_path,
                           MARKETStruct* marketShmPtr,
                           boost::asio::io_context& ioc,
                           boost::asio::ssl::context& ssl_ctx);
    ~BinanceClient();
    void run();

private:
    void subscribeMarkets();
    // void subscribeTrades();
    void initOrderBooks();
    void getCurrentOrderBook(const std::string& symbol);
    void updateOrderBook();
    void handleMarketMessage(const std::string& msg);
    // void handleTradeMessage(const std::string& msg);
    // void handleOrderBookInit(int market_id, const rapidjson::Document& doc);
    // void handleOrderBookUpdate(int market_id, const rapidjson::Document& doc);
    // void handleAccountUpdateTrades(const rapidjson::Document& doc);
    // void handleOrdersResponse(const rapidjson::Document& doc);
    void printOrderBooks() const;
    //下单
    // void quantLoop();
    // long long int getNextNonce();
    
private:
    //行情ws
    std::shared_ptr<WSConnection> mdConn_;
    //交易ws
    // std::shared_ptr<WSConnection> tdConn_;
    //restful api
    std::shared_ptr<HttpsConnectionPool> httpsConnPool_;
    //配置文件
    std::string config_path_;
    // 共享内存指针
    MARKETStruct* marketShmPtr_;

    // 本地维护的订单簿深度 
    int orderbook_depth_;
    // 本地维护的 OrderBook 
    std::unordered_map<std::string, BinanceOrderBook> orderBooks_;
    // 订单簿更新缓存
    std::unordered_map<std::string, std::list<BinanceOrderBookUpdate>> orderBookUpdates_;
    // symbol到到后increament u的映射
    std::unordered_map<std::string, long long int> symbol_u_;

    // 连接参数
    std::string ws_host_;
    std::string ws_port_;
    std::string https_host_;
    std::string https_port_;

    // 写入前N档到共享内存
    void writeTopNLevelsToShm(const std::string& symbol, const BinanceOrderBook& book);
    // 检查更新是否影响前N档并写入共享内存
    void checkAndWriteUpdateToShm(const std::string& symbol,
                                   const BinanceOrderBook& book,
                                   uint64_t price,
                                   double size,
                                   OrderSideEnum side);
};